fix(frontend): show 'device deleted' status for tasks with deleted de…#857
fix(frontend): show 'device deleted' status for tasks with deleted de…#857FicoHu wants to merge 7 commits intowecode-ai:mainfrom
Conversation
…vices When a device is deleted, historical chat sessions associated with that device now display a clear "Device Deleted" status instead of incorrectly showing "Public Mode". This provides better UX consistency: - DeviceSelectorTab: Shows red "Device Deleted" badge when task's device is deleted - Device chat page: Top device selector shows deletion status - Chat input is disabled with appropriate hint message Co-Authored-By: Claude Opus 4.5 <[email protected]>
📝 WalkthroughWalkthroughDetects when a task's associated device ID is missing from the loaded devices and surfaces that across chat UIs: hide the device selector, prefer a deleted-device hint for disabling input, show an overlay with a link to start a new chat, and add i18n keys. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as Chat UI
participant Task as SelectedTaskDetail
participant Devices as DeviceContext
participant Router as Router/Paths
UI->>Task: read selectedTaskDetail.device_id
UI->>Devices: read current devices list
Devices-->>UI: devices[]
alt task device id missing
UI->>UI: set isTaskDeviceDeleted = true
UI->>UI: hide device selector
UI->>UI: show deleted-device overlay / disabled hint
UI->>Router: link to start new chat (paths.chat.getHref)
else task device present
UI->>UI: render device selector / status pill
UI->>UI: compute disabledReason from device status
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsTimed out fetching pipeline failures after 30000ms Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/app/`(tasks)/devices/chat/page.tsx:
- Around line 129-133: isTaskDeviceDeleted currently treats an empty devices
array as "deleted" during initial load; update its logic in the useMemo that
defines isTaskDeviceDeleted to also check the DeviceContext loading flag
(isLoading) and return false while devices are still loading. Specifically,
modify the useMemo that references selectedTaskDetail?.device_id and devices so
it references the isLoading value from DeviceContext (or the provider hook) and
short-circuits to false when isLoading is true, then proceed to the existing
devices.some(...) check to determine real deletion status.
In `@frontend/src/features/tasks/components/input/DeviceSelectorTab.tsx`:
- Around line 331-336: The isTaskDeviceDeleted memo in DeviceSelectorTab.tsx can
return a false positive while devices are still loading; update the useMemo
(isTaskDeviceDeleted) to also guard against the devices loading state from
useDevices by returning false when isLoading is true (in addition to the
existing hasMessages/taskDeviceId checks), so the memo only treats a device as
deleted once loading has finished and the devices list is definitive.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 244a7f74-85a0-4f71-becf-e09a3551b1aa
📒 Files selected for processing (4)
frontend/src/app/(tasks)/devices/chat/page.tsxfrontend/src/features/tasks/components/input/DeviceSelectorTab.tsxfrontend/src/i18n/locales/en/devices.jsonfrontend/src/i18n/locales/zh-CN/devices.json
| // Check if task was associated with a device that has been deleted | ||
| const isTaskDeviceDeleted = useMemo(() => { | ||
| if (!selectedTaskDetail?.device_id) return false | ||
| return !devices.some(d => d.device_id === selectedTaskDetail.device_id) | ||
| }, [selectedTaskDetail?.device_id, devices]) |
There was a problem hiding this comment.
Race condition: false positive during initial device loading.
The isTaskDeviceDeleted check doesn't account for the loading state of the devices list. According to DeviceContext, devices initializes as an empty array while isLoading is true. This means any task with a device_id will incorrectly show "Device Deleted" status during the initial load before the devices fetch completes.
🐛 Proposed fix: Check `isLoading` before determining deletion status
+ const { devices, selectedDeviceId, setSelectedDeviceId, isLoading: isDevicesLoading } = useDevices()
// Check if task was associated with a device that has been deleted
const isTaskDeviceDeleted = useMemo(() => {
+ // Don't report as deleted while devices are still loading
+ if (isDevicesLoading) return false
if (!selectedTaskDetail?.device_id) return false
return !devices.some(d => d.device_id === selectedTaskDetail.device_id)
- }, [selectedTaskDetail?.device_id, devices])
+ }, [selectedTaskDetail?.device_id, devices, isDevicesLoading])🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/src/app/`(tasks)/devices/chat/page.tsx around lines 129 - 133,
isTaskDeviceDeleted currently treats an empty devices array as "deleted" during
initial load; update its logic in the useMemo that defines isTaskDeviceDeleted
to also check the DeviceContext loading flag (isLoading) and return false while
devices are still loading. Specifically, modify the useMemo that references
selectedTaskDetail?.device_id and devices so it references the isLoading value
from DeviceContext (or the provider hook) and short-circuits to false when
isLoading is true, then proceed to the existing devices.some(...) check to
determine real deletion status.
| // Check if the task was associated with a device that has been deleted | ||
| const isTaskDeviceDeleted = useMemo(() => { | ||
| if (!hasMessages || !taskDeviceId) return false | ||
| // If taskDeviceId exists but device not found in devices list, it means the device was deleted | ||
| return !devices.some(device => device.device_id === taskDeviceId) | ||
| }, [hasMessages, taskDeviceId, devices]) |
There was a problem hiding this comment.
Same race condition as in page.tsx: false positive during device loading.
This memo has the same issue as the one in page.tsx. When devices is still loading (empty array), tasks with a device_id will incorrectly appear as having a deleted device. The isLoading state from useDevices should be checked.
🐛 Proposed fix: Guard against loading state
- const { devices, selectedDeviceId, setSelectedDeviceId, isLoading } = useDevices()
+ const { devices, selectedDeviceId, setSelectedDeviceId, isLoading: isDevicesLoading } = useDevices()
// Check if the task was associated with a device that has been deleted
const isTaskDeviceDeleted = useMemo(() => {
+ // Don't report as deleted while devices are still loading
+ if (isDevicesLoading) return false
if (!hasMessages || !taskDeviceId) return false
// If taskDeviceId exists but device not found in devices list, it means the device was deleted
return !devices.some(device => device.device_id === taskDeviceId)
- }, [hasMessages, taskDeviceId, devices])
+ }, [hasMessages, taskDeviceId, devices, isDevicesLoading])Note: isLoading is already destructured on line 230, so you can use it directly instead of renaming:
const isTaskDeviceDeleted = useMemo(() => {
+ if (isLoading) return false
if (!hasMessages || !taskDeviceId) return false
return !devices.some(device => device.device_id === taskDeviceId)
- }, [hasMessages, taskDeviceId, devices])
+ }, [hasMessages, taskDeviceId, devices, isLoading])🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/src/features/tasks/components/input/DeviceSelectorTab.tsx` around
lines 331 - 336, The isTaskDeviceDeleted memo in DeviceSelectorTab.tsx can
return a false positive while devices are still loading; update the useMemo
(isTaskDeviceDeleted) to also guard against the devices loading state from
useDevices by returning false when isLoading is true (in addition to the
existing hasMessages/taskDeviceId checks), so the memo only treats a device as
deleted once loading has finished and the devices list is definitive.
- Hide the device selector in top navigation when task's device is deleted - Add "Start New Chat" link next to "Device Deleted" badge in input area - Users can now easily create a new conversation when viewing deleted device tasks Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove device deleted badge from DeviceSelectorTab (return null when deleted) - Add clickable overlay in ChatInputCard when task's device is deleted - Show centered "Device deleted" message with "Start New Chat" button - Cleaner UI that follows Calm UI design principles Co-Authored-By: Claude Opus 4.5 <[email protected]>
- For existing tasks with device_id, show the device name and status even if the device is offline (read-only display) - Only show device selector dropdown for new tasks - Correctly handle disabledReason when task's device is offline Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Check task's device_id when computing disabledReason, not just selectedDeviceId - Show "device deleted" hint when task's device no longer exists - Show "device offline" hint when task's device is offline - Applies to both ChatPageDesktop and ChatPageMobile Co-Authored-By: Claude Opus 4.5 <[email protected]>
When a task has a device_id but the device is not in the current devices list (loading or deleted), show a placeholder with offline indicator instead of misleading "Public Mode" text. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
frontend/src/features/tasks/components/input/ChatInputCard.tsx (1)
269-281: Consider accessibility for the overlay.The overlay blocks interaction with the underlying input but doesn't trap focus or announce itself to screen readers. Users relying on assistive technology may not understand why the input is inaccessible.
Consider adding
role="alertdialog"andaria-modal="true"to the overlay container, and ensure the "Start New Chat" link receives focus when the overlay appears.♿ Suggested accessibility improvement
{/* Device Deleted Overlay - shows clickable prompt when task's device is deleted */} {isTaskDeviceDeleted && ( - <div className="absolute inset-0 z-40 rounded-3xl bg-base/95 backdrop-blur-sm flex flex-col items-center justify-center transition-all"> + <div + role="alertdialog" + aria-modal="true" + aria-label={t('devices:device_deleted_hint')} + className="absolute inset-0 z-40 rounded-3xl bg-base/95 backdrop-blur-sm flex flex-col items-center justify-center transition-all" + > <p className="text-sm text-text-muted mb-3">{t('devices:device_deleted_hint')}</p> <Link href={paths.chat.getHref()} className="flex items-center gap-1.5 px-4 py-2 rounded-full bg-primary text-white text-sm font-medium hover:bg-primary/90 transition-colors" >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/features/tasks/components/input/ChatInputCard.tsx` around lines 269 - 281, The overlay rendered when isTaskDeviceDeleted in ChatInputCard isn't accessible: add role="alertdialog" and aria-modal="true" to the overlay container element and ensure the "Start New Chat" Link receives focus when the overlay appears; implement a ref for the Link (or a wrapper focusable element) and use an effect that runs when isTaskDeviceDeleted becomes true to call focus(), and consider adding simple focus trapping within the overlay while it's visible so keyboard users cannot tab into the underlying input.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/app/`(tasks)/chat/ChatPageDesktop.tsx:
- Around line 62-69: The isTaskDeviceDeleted check can return a false positive
while devices are loading; update the logic to extract the loading flag from
useDevices() (e.g., isLoading or similar) and only compute isTaskDeviceDeleted
when loading is false and selectedTaskDetail?.device_id exists, otherwise treat
it as not deleted; keep taskDevice and isTaskDeviceOffline computations the same
but ensure any UI that shows "Device Deleted" depends on the guarded
isTaskDeviceDeleted.
In `@frontend/src/app/`(tasks)/chat/ChatPageMobile.tsx:
- Around line 51-58: The isTaskDeviceDeleted computation can return a false
positive while devices are still loading; update ChatPageMobile to extract the
isLoading flag from useDevices() (same hook used to get devices) and guard the
deletion check so that isTaskDeviceDeleted is false while isLoading is true;
specifically modify the logic around selectedTaskDetail, devices and the
isTaskDeviceDeleted variable to include !isLoading &&
selectedTaskDetail?.device_id && !devices.some(...), matching the pattern used
in ChatPageDesktop.
In `@frontend/src/features/tasks/components/chat/ChatArea.tsx`:
- Around line 116-123: The isTaskDeviceDeleted calculation can return a false
positive while devices are still loading; update the useDevices() call to also
extract isLoading (e.g., const { devices, isLoading } = useDevices()) and modify
the useMemo for isTaskDeviceDeleted to return false when isLoading is true (or
when devices is undefined/null), keeping the existing checks on
selectedTaskDetail?.device_id and the devices.some(...) logic otherwise; this
ensures the useMemo (isTaskDeviceDeleted) only reports deletion after devices
have finished loading.
---
Nitpick comments:
In `@frontend/src/features/tasks/components/input/ChatInputCard.tsx`:
- Around line 269-281: The overlay rendered when isTaskDeviceDeleted in
ChatInputCard isn't accessible: add role="alertdialog" and aria-modal="true" to
the overlay container element and ensure the "Start New Chat" Link receives
focus when the overlay appears; implement a ref for the Link (or a wrapper
focusable element) and use an effect that runs when isTaskDeviceDeleted becomes
true to call focus(), and consider adding simple focus trapping within the
overlay while it's visible so keyboard users cannot tab into the underlying
input.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6ab60539-8c74-46c4-867c-498f609732f4
📒 Files selected for processing (8)
frontend/src/app/(tasks)/chat/ChatPageDesktop.tsxfrontend/src/app/(tasks)/chat/ChatPageMobile.tsxfrontend/src/app/(tasks)/devices/chat/page.tsxfrontend/src/features/tasks/components/chat/ChatArea.tsxfrontend/src/features/tasks/components/input/ChatInputCard.tsxfrontend/src/features/tasks/components/input/DeviceSelectorTab.tsxfrontend/src/i18n/locales/en/devices.jsonfrontend/src/i18n/locales/zh-CN/devices.json
✅ Files skipped from review due to trivial changes (2)
- frontend/src/i18n/locales/zh-CN/devices.json
- frontend/src/i18n/locales/en/devices.json
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/src/features/tasks/components/input/DeviceSelectorTab.tsx
| // For existing tasks, also check the task's device_id | ||
| const taskDevice = selectedTaskDetail?.device_id | ||
| ? devices.find(d => d.device_id === selectedTaskDetail.device_id) | ||
| : null | ||
| const isTaskDeviceDeleted = | ||
| selectedTaskDetail?.device_id && | ||
| !devices.some(d => d.device_id === selectedTaskDetail.device_id) | ||
| const isTaskDeviceOffline = taskDevice?.status === 'offline' |
There was a problem hiding this comment.
Race condition: false positive during initial device loading.
The isTaskDeviceDeleted check doesn't account for the devices loading state. When devices initializes as an empty array while fetching, any task with a device_id will incorrectly show "Device Deleted" status until the fetch completes.
This is the same issue identified in frontend/src/app/(tasks)/devices/chat/page.tsx. Consider extracting isLoading from useDevices() and guarding against it.
🐛 Proposed fix: Check loading state before determining deletion status
// Device context - when a device is selected, switch to 'task' mode
- const { selectedDeviceId, devices } = useDevices()
+ const { selectedDeviceId, devices, isLoading: isDevicesLoading } = useDevices()
const selectedDevice = devices.find(d => d.device_id === selectedDeviceId)
// For existing tasks, also check the task's device_id
const taskDevice = selectedTaskDetail?.device_id
? devices.find(d => d.device_id === selectedTaskDetail.device_id)
: null
const isTaskDeviceDeleted =
+ !isDevicesLoading &&
selectedTaskDetail?.device_id &&
!devices.some(d => d.device_id === selectedTaskDetail.device_id)
const isTaskDeviceOffline = taskDevice?.status === 'offline'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/src/app/`(tasks)/chat/ChatPageDesktop.tsx around lines 62 - 69, The
isTaskDeviceDeleted check can return a false positive while devices are loading;
update the logic to extract the loading flag from useDevices() (e.g., isLoading
or similar) and only compute isTaskDeviceDeleted when loading is false and
selectedTaskDetail?.device_id exists, otherwise treat it as not deleted; keep
taskDevice and isTaskDeviceOffline computations the same but ensure any UI that
shows "Device Deleted" depends on the guarded isTaskDeviceDeleted.
| // For existing tasks, also check the task's device_id | ||
| const taskDevice = selectedTaskDetail?.device_id | ||
| ? devices.find(d => d.device_id === selectedTaskDetail.device_id) | ||
| : null | ||
| const isTaskDeviceDeleted = | ||
| selectedTaskDetail?.device_id && | ||
| !devices.some(d => d.device_id === selectedTaskDetail.device_id) | ||
| const isTaskDeviceOffline = taskDevice?.status === 'offline' |
There was a problem hiding this comment.
Race condition: false positive during initial device loading.
Same issue as ChatPageDesktop.tsx: the isTaskDeviceDeleted check doesn't account for the devices loading state. Extract isLoading from useDevices() and guard against it.
🐛 Proposed fix: Check loading state before determining deletion status
// Device context - when a device is selected, switch to 'task' mode
- const { selectedDeviceId, devices } = useDevices()
+ const { selectedDeviceId, devices, isLoading: isDevicesLoading } = useDevices()
const selectedDevice = devices.find(d => d.device_id === selectedDeviceId)
// For existing tasks, also check the task's device_id
const taskDevice = selectedTaskDetail?.device_id
? devices.find(d => d.device_id === selectedTaskDetail.device_id)
: null
const isTaskDeviceDeleted =
+ !isDevicesLoading &&
selectedTaskDetail?.device_id &&
!devices.some(d => d.device_id === selectedTaskDetail.device_id)
const isTaskDeviceOffline = taskDevice?.status === 'offline'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/src/app/`(tasks)/chat/ChatPageMobile.tsx around lines 51 - 58, The
isTaskDeviceDeleted computation can return a false positive while devices are
still loading; update ChatPageMobile to extract the isLoading flag from
useDevices() (same hook used to get devices) and guard the deletion check so
that isTaskDeviceDeleted is false while isLoading is true; specifically modify
the logic around selectedTaskDetail, devices and the isTaskDeviceDeleted
variable to include !isLoading && selectedTaskDetail?.device_id &&
!devices.some(...), matching the pattern used in ChatPageDesktop.
| // Device context - for detecting deleted device | ||
| const { devices } = useDevices() | ||
|
|
||
| // Check if task was associated with a device that has been deleted | ||
| const isTaskDeviceDeleted = useMemo(() => { | ||
| if (!selectedTaskDetail?.device_id) return false | ||
| return !devices.some(d => d.device_id === selectedTaskDetail.device_id) | ||
| }, [selectedTaskDetail?.device_id, devices]) |
There was a problem hiding this comment.
Race condition: false positive during initial device loading.
Same issue as in the page components: when devices is still loading (empty array), any task with a device_id will incorrectly report as deleted. Extract isLoading from useDevices() and check it in the useMemo.
🐛 Proposed fix: Guard against loading state
// Device context - for detecting deleted device
- const { devices } = useDevices()
+ const { devices, isLoading: isDevicesLoading } = useDevices()
// Check if task was associated with a device that has been deleted
const isTaskDeviceDeleted = useMemo(() => {
+ // Don't report as deleted while devices are still loading
+ if (isDevicesLoading) return false
if (!selectedTaskDetail?.device_id) return false
return !devices.some(d => d.device_id === selectedTaskDetail.device_id)
- }, [selectedTaskDetail?.device_id, devices])
+ }, [selectedTaskDetail?.device_id, devices, isDevicesLoading])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Device context - for detecting deleted device | |
| const { devices } = useDevices() | |
| // Check if task was associated with a device that has been deleted | |
| const isTaskDeviceDeleted = useMemo(() => { | |
| if (!selectedTaskDetail?.device_id) return false | |
| return !devices.some(d => d.device_id === selectedTaskDetail.device_id) | |
| }, [selectedTaskDetail?.device_id, devices]) | |
| // Device context - for detecting deleted device | |
| const { devices, isLoading: isDevicesLoading } = useDevices() | |
| // Check if task was associated with a device that has been deleted | |
| const isTaskDeviceDeleted = useMemo(() => { | |
| // Don't report as deleted while devices are still loading | |
| if (isDevicesLoading) return false | |
| if (!selectedTaskDetail?.device_id) return false | |
| return !devices.some(d => d.device_id === selectedTaskDetail.device_id) | |
| }, [selectedTaskDetail?.device_id, devices, isDevicesLoading]) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@frontend/src/features/tasks/components/chat/ChatArea.tsx` around lines 116 -
123, The isTaskDeviceDeleted calculation can return a false positive while
devices are still loading; update the useDevices() call to also extract
isLoading (e.g., const { devices, isLoading } = useDevices()) and modify the
useMemo for isTaskDeviceDeleted to return false when isLoading is true (or when
devices is undefined/null), keeping the existing checks on
selectedTaskDetail?.device_id and the devices.some(...) logic otherwise; this
ensures the useMemo (isTaskDeviceDeleted) only reports deletion after devices
have finished loading.
When viewing a historical task that was created with cloud mode (device_id=null) on the /devices/chat page, the input should not be disabled. Previously, if no device was selected globally, it would show "device offline" error even for cloud mode tasks. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
🧹 Nitpick comments (2)
frontend/src/app/(tasks)/devices/chat/page.tsx (2)
206-225: Consider adding accessibility attributes to the device selector.The
<select>element lacks anidattribute and associated<label>for screen reader users. Adding these would improve accessibility.♿ Proposed accessibility improvement
+ <label htmlFor="device-selector" className="sr-only"> + {t('select_device')} + </label> <select + id="device-selector" value={selectedDeviceId || ''} onChange={e => handleDeviceSelect(e.target.value)} className="bg-surface border border-border rounded-md px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-primary/20" + aria-label={t('select_device')} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/app/`(tasks)/devices/chat/page.tsx around lines 206 - 225, The device <select> lacks an accessible label; add an <label> element tied to the select via an id and htmlFor (or add a stable id on the select and use aria-labelledby/aria-label) so screen readers announce the control; update the select (currently using selectedDeviceId and handleDeviceSelect and rendering devices) to include an id (e.g., device-select) and add a visible or visually-hidden <label> with the translated text (t('select_device')) to associate with it.
130-131: Comment doesn't match the implementation.The comment states "non-empty title and was created" but the code only checks for
selectedTaskDetail.id. Consider updating the comment to accurately reflect the logic.📝 Suggested comment fix
- // Task is considered to have messages if it has a non-empty title and was created + // Task is considered to have messages if it was created (has an id) const hasMessages = !!(selectedTaskDetail && selectedTaskDetail.id)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/app/`(tasks)/devices/chat/page.tsx around lines 130 - 131, The comment above the hasMessages computation is misleading: it says "non-empty title and was created" but the code only checks selectedTaskDetail && selectedTaskDetail.id; update the comment to accurately describe the logic (e.g., "Task is considered to have messages if a selected task exists (has an id)") or change the condition if you intended to check title; references: hasMessages and selectedTaskDetail/selectedTaskDetail.id.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@frontend/src/app/`(tasks)/devices/chat/page.tsx:
- Around line 206-225: The device <select> lacks an accessible label; add an
<label> element tied to the select via an id and htmlFor (or add a stable id on
the select and use aria-labelledby/aria-label) so screen readers announce the
control; update the select (currently using selectedDeviceId and
handleDeviceSelect and rendering devices) to include an id (e.g., device-select)
and add a visible or visually-hidden <label> with the translated text
(t('select_device')) to associate with it.
- Around line 130-131: The comment above the hasMessages computation is
misleading: it says "non-empty title and was created" but the code only checks
selectedTaskDetail && selectedTaskDetail.id; update the comment to accurately
describe the logic (e.g., "Task is considered to have messages if a selected
task exists (has an id)") or change the condition if you intended to check
title; references: hasMessages and selectedTaskDetail/selectedTaskDetail.id.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 87461b4b-f2e6-4512-a8e5-8eb61b658c33
📒 Files selected for processing (1)
frontend/src/app/(tasks)/devices/chat/page.tsx
…vices
When a device is deleted, historical chat sessions associated with that device now display a clear "Device Deleted" status instead of incorrectly showing "Public Mode". This provides better UX consistency:
Summary by CodeRabbit
New Features
Localization